//-----------------------------------------------------------------------------
// Author - Marco Martinelli - https://github.com/martinellimarco
//-----------------------------------------------------------------------------

#ifndef _MSVAD_IVSHMEM_SAVEDATA_H
#define _MSVAD_IVSHMEM_SAVEDATA_H

#pragma warning(push)
#pragma warning(disable:4201) // nameless struct/union
#pragma warning(disable:4214) // bit field types other than int

#include <ntddk.h>

#pragma warning(pop)

#include "shared_mem.h"

//-----------------------------------------------------------------------------
//  Forward declaration
//-----------------------------------------------------------------------------
class CIVSHMEMSaveData;
typedef CIVSHMEMSaveData *PCIVSHMEMSaveData;

//-----------------------------------------------------------------------------
//  Structs
//-----------------------------------------------------------------------------

// Parameter to workitem.
#include <pshpack1.h>
typedef struct _IVSHMEM_SAVEWORKER_PARAM {
    PIO_WORKITEM        WorkItem;
    PCIVSHMEMSaveData   pSaveData;
    KEVENT              EventDone;
} IVSHMEM_SAVEWORKER_PARAM;
typedef IVSHMEM_SAVEWORKER_PARAM *PIVSHMEM_SAVEWORKER_PARAM;
#include <poppack.h>

typedef struct IVSHMEM_PLAYBACK
{
    UINT16  chunkIdx;
    UINT32  offset;    //position of the 1st chunk
    UINT16  maxChunks; //how many chunks
    UINT32  chunkSize; //the size of a chunk
    UINT32  bufferSize;
}
IVSHMEM_OBJECT, *PIVSHMEM_OBJECT;

//-----------------------------------------------------------------------------
//  Classes
//-----------------------------------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
// CIVSHMEMSaveData
//   Saves the wave data to disk.
//
IO_WORKITEM_ROUTINE IVSHMEMSendDataWorkerCallback;

class CIVSHMEMSaveData {
protected:
    ULONG                       m_ulChunkOffset;

    static PDEVICE_OBJECT       m_pDeviceObject;

    IVSHMEM_PLAYBACK            m_ivshmem;
    IVSHMEM_SCREAM_STREAM_HEADER *m_pStreamHdr;

public:
    CIVSHMEMSaveData();
    ~CIVSHMEMSaveData();

    NTSTATUS                    Initialize(PVOID sharedMemPtr, UINT uSharedMemSize, BOOLEAN fCapture,
                                           DWORD nSamplesPerSec, WORD wBitsPerSample,
                                           WORD nChannels, DWORD dwChannelMask);
    void                        Disable(BOOL fDisable);

    void                        WriteData(IN PBYTE pBuffer, IN ULONG ulByteCount);
    void                        ReadData(IN PBYTE pBuffer, IN ULONG ulByteCount);
    ULONG                       ReadableDataLength(VOID);

private:
    PVOID                       m_pSharedMem;
    UINT                        m_SharedMemSize;
    BOOLEAN                     m_fCapture;
};
typedef CIVSHMEMSaveData *PCIVSHMEMSaveData;

#endif
